﻿<title>Switch Streams / WebRTC Experiment / Muaz Khan</title>
<link rel="author" type="text/html" href="https://plus.google.com/100325991024054712503">
<meta name="author" content="Muaz Khan">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">

<blockquote style="background: #f3b7b7;border: 5px solid black;border-radius: 5px;padding: 5px 10px; margin: 10px 20px;">
    This demo is <span style="border: 1px dotted red; background: yellow; padding: 2px 5px;">out-dated (published on 2013)</span>. Please check this instead: <a href="https://github.com/webrtc/samples">https://github.com/webrtc/samples</a>
</blockquote>

<div style="text-align: center;">
    <button id="switch-stream">
        Switch Stream to Audio+Video</button>
    <hr />
    <div class="videos-container">
        <video id="peer2-to-peer1" autoplay controls></video>
        <h2>
            Offerer-to-Answerer</h2>
    </div>
    <div class="videos-container">
        <video id="peer1-to-peer2" autoplay controls></video>
        <h2>
            Answerer-to-Offerer</h2>
    </div>
    <hr />
    <h2>Switch Streams / <a href="https://www.webrtc-experiment.com/">WebRTC Experiment</a></h2>
    <p>Switching streams from screen-sharing to audio+video at runtime. (Renegotiation) / Read <a href="https://www.webrtc-experiment.com/docs/how-to-switch-streams.html" target="_blank">how to switch streams?</a></p>
</div>

<script src="https://cdn.WebRTC-Experiment.com/getScreenId.js"></script>

<script>
    var mediaConstraints = {
        optional: [],
        mandatory: {
            OfferToReceiveAudio: true,
            OfferToReceiveVideo: true
        }
    };
	
	/*jshint -W079 */
	var URL = window.URL;

	if (typeof URL === 'undefined' && typeof webkitURL !== 'undefined') {
		/*global URL:true */
		URL = webkitURL;
	}
	
	var MediaStream = window.MediaStream;

	if (typeof MediaStream === 'undefined' && typeof webkitMediaStream !== 'undefined') {
		MediaStream = webkitMediaStream;
	}

	/*global MediaStream:true */
	if (typeof MediaStream !== 'undefined') {
		if (!('getVideoTracks' in MediaStream.prototype)) {
			MediaStream.prototype.getVideoTracks = function() {
				if (!this.getTracks) {
					return [];
				}

				var tracks = [];
				this.getTracks.forEach(function(track) {
					if (track.kind.toString().indexOf('video') !== -1) {
						tracks.push(track);
					}
				});
				return tracks;
			};

			MediaStream.prototype.getAudioTracks = function() {
				if (!this.getTracks) {
					return [];
				}

				var tracks = [];
				this.getTracks.forEach(function(track) {
					if (track.kind.toString().indexOf('audio') !== -1) {
						tracks.push(track);
					}
				});
				return tracks;
			};
		}

		if (!('stop' in MediaStream.prototype)) {
			MediaStream.prototype.stop = function() {
				this.getAudioTracks().forEach(function(track) {
					if (!!track.stop) {
						track.stop();
					}
				});

				this.getVideoTracks().forEach(function(track) {
					if (!!track.stop) {
						track.stop();
					}
				});
			};
		}
	}
</script>

<script>
    var offerer, answerer;
    var offererToAnswerer = document.getElementById('peer1-to-peer2');
    var answererToOfferer = document.getElementById('peer2-to-peer1');

    window.RTCPeerConnection = window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
    window.RTCSessionDescription = window.mozRTCSessionDescription || window.RTCSessionDescription;
    window.RTCIceCandidate = window.mozRTCIceCandidate || window.RTCIceCandidate;

    navigator.getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
    window.URL = window.webkitURL || window.URL;

    window.iceServers = {
        iceServers: [{
            urls: 'stun:stun.l.google.com:19302'
        }, {
			urls: 'stun:webrtcweb.com:4455',
			username: 'muazkh',
			credential: 'muazkh'
		}]
    };
</script>

<script>
    /* offerer */

    function offererPeer(e) {
        if (!e.switching) offerer = new RTCPeerConnection(window.iceServers);
        if (old_stream) offerer.removeStream(old_stream);
        offerer.addStream(e.stream);

        offerer.onaddstream = function(event) {
            offererToAnswerer.src = URL.createObjectURL(event.stream);
            offererToAnswerer.play();
        };

        offerer.onicecandidate = function(event) {
            if (e.switching) return;

            if (!event || !event.candidate) return;
            answerer.addIceCandidate(event.candidate);

            console.log('\r\n----ice gathered by offerer-----\r\n');
            console.log(event.candidate.candidate);
        };

        offerer.createOffer(function(offer) {
            offerer.setLocalDescription(offer);
            answererPeer(offer, e.stream, e.switching);

            console.log('\r\n----offer-----\r\n');
            console.log(offer.sdp);
        }, function() {}, mediaConstraints);
    }
</script>

<script>
    /* answerer */

    function answererPeer(offer, stream, switching) {
        if (!switching) answerer = new RTCPeerConnection(window.iceServers);
        if (old_stream) answerer.removeStream(old_stream);
        answerer.addStream(stream);

        answerer.onaddstream = function(event) {
            answererToOfferer.src = URL.createObjectURL(event.stream);
            answererToOfferer.play();
        };

        answerer.onicecandidate = function(event) {
            if (switching) return;

            if (!event || !event.candidate) return;
            offerer.addIceCandidate(event.candidate);

            console.log('\r\n----ice gathered by answerer-----\r\n');
            console.log(event.candidate.candidate);
        };

        answerer.setRemoteDescription(offer);
        answerer.createAnswer(function(answer) {
            answerer.setLocalDescription(answer);
            offerer.setRemoteDescription(answer);

            console.log('\r\n----answer-----\r\n');
            console.log(answer.sdp);
        }, function() {}, mediaConstraints);
    }
</script>

<script>
    var video_constraints = {
        mandatory: { },
        optional: []
    };

    function getUserMedia(callback, constraints) {
		console.info('getUserMedia', constraints);
		
        var n = navigator;
        n.getMedia = n.webkitGetUserMedia || n.mozGetUserMedia;
        n.getMedia(constraints || {
            audio: true,
            video: video_constraints
        }, callback, onerror);

        function onerror(e) {
            console.error(e);

            if (location.protocol === 'http:') {
                throw '<https> is mandatory to capture screen.';
            } else {
                throw 'Screen capturing process is denied. Are you enabled flag: "Enable screen capture support in getUserMedia"?';
            }
        }
    }
</script>

<!-- screen capturing stream -->
<script>
    var old_stream;
    
	function captureScreen() {
		getScreenId(function (error, sourceId, screen_constraints) {
			console.info('getScreenId', error, sourceId, screen_constraints);
			getUserMedia(function(stream) {
				old_stream = stream;

				console.log(JSON.stringify(screen_constraints, null, '\t'), stream);
				offererPeer({
					stream: stream
				});
			}, screen_constraints);
		});
	}
	
	var maxTries = 0;

	function showChromeExtensionStatus() {
		if (typeof window.getChromeExtensionStatus !== 'function') return captureScreen();

		var gotResponse;
		window.getChromeExtensionStatus(function(status) {
			gotResponse = true;
			console.info('getChromeExtensionStatus', status);
			
			captureScreen();
		});

		maxTries++;
		if (maxTries > 15) return;
		setTimeout(function() {
			if (!gotResponse) showChromeExtensionStatus();
		}, 1000);
	}

	showChromeExtensionStatus();
</script>

<!-- switch streams to audio+video -->
<script>
    document.getElementById('switch-stream').onclick = function() {
        this.disabled = true;
        if(old_stream) old_stream.stop();
        getUserMedia(function(stream) {
            console.log('audio+video stream', stream);
            offererPeer({
                stream: stream,
                switching: true
            });
        });
    };
</script>

<!-- CSS -->
<style>
    html { background: #eee; }

    button, input[type=button] {
        -moz-border-radius: 3px;
        -moz-transition: none;
        -webkit-transition: none;
        background: #0370ea;
        background: -moz-linear-gradient(top, #008dfd 0, #0370ea 100%);
        background: -webkit-linear-gradient(top, #008dfd 0, #0370ea 100%);
        border: 1px solid #076bd2;
        border-radius: 3px;
        color: #fff;
        display: inline-block;
        font-family: inherit;
        font-size: .8em;
        font-size: 1.5em;
        line-height: 1.3;
        padding: 5px 12px;
        text-align: center;
        text-shadow: 1px 1px 1px #076bd2;
    }

    button:hover, input[type=button]:hover { background: rgb(9, 147, 240); }

    button:active, input[type=button]:active { background: rgb(10, 118, 190); }

    button[disabled], input[type=button][disabled] {
        background: none;
        border: 1px solid rgb(187, 181, 181);
        color: gray;
        text-shadow: none;
    }

    .videos-container {
        background: white;
        border: 2px solid black;
        border-radius: 0.2em;
        display: inline-block;
        margin: 2em .2em;
        padding: .1em;
        vertical-align: top;
    }

    .videos-container h2 {
        border: 0;
        border-top: 1px solid black;
        display: block;
        margin: 0;
        text-align: center;
    }

    video {
        background: black;
        height: 15em;
        width: 20em;
    }
</style>

<section class="experiment">
	<h2 class="header" id="feedback">Feedback</h2>
	<div><textarea id="message" style="height: 8em; margin: .2em; width: 98%; border: 1px solid rgb(189, 189, 189); outline: none; resize: vertical;" placeholder="Have any message? Suggestions or something went wrong?"></textarea></div>
	<button id="send-message" style="font-size: 1em;">Send Message</button><small style="margin-left:1em;">Enter your email too; if you want "direct" reply!</small>
</section>
<script src="https://cdn.webrtc-experiment.com/commits.js" async></script>